/*
 * Serial terminal server on port 8250 ... uses polling which is terrible.
 * Investigate using streams. Will hyperstream serve the need?
 *
 * The transmit side is not complete.
 *
 * A lock file is needed for separate com server from the build/load server.
 */
var http = require('http'),
      fs = require('fs'),
     url = require('url'),
 pathobj = require('path');

var exec = require('child_process').exec;
var com  = require("serialport");

var serialPort = 0;

/*
 * We read the port name from a file created by the main server.
 * The file is written after a load operation succeeds.
 */

var portOnline = 0;
var portfile   = "workspace/portresult.txt";
var datafile   = "workspace/serialdata.txt";

var isWindows= /^win/.test(process.platform);

var child = exec('date',
function(error, stdout, stderr) {
    console.log("Starting com server.");
});

var tip = 0;

function winsep(str)
{
  if (isWindows) {
    while (str.indexOf('/') > -1) {
      str = str.replace('/','\\');
    }
    console.log(str);
  }
  return str;
}

function callbackReplyOk(response, error, stdout, stderr)
{
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end(stdout);
  if (error) console.log(error.code);
}

function serialReceive(data)
{
/*
  // this is an option for server testing
  var da = data.split("\n");
  var datalines = da.length > 0 ? da.length : 1;

  fs.writeFileSync(datafile, "");

  if (fs.existsSync(datafile)) {
    var bf = String(fs.readFileSync(datafile));
    var sa = bf.split("\n");
    var mx = 31-datalines;
    var n  = sa.length > mx ? sa.length-mx : 0;
    console.log(n + " " + sa.length);
    for(; n < sa.length; n++) {
      console.log(sa[n]);
      fs.appendFileSync(datafile, sa[n]);
    }
  }

  console.log(datalines);
  console.log(data);

  fs.appendFileSync(datafile, data);

  for(var n = 1; n < datalines; n++) {
    console.log(da[n]);
    fs.appendFileSync(datafile, da[n]);
  }
*/
  //console.log(data);
  // let the client handle the data
  fs.writeFile(datafile, data, function(err) {
    if (err) console.log("Error writing datafile: "+datafile);
  });
}

var querystring = require('querystring');

http.createServer(
function(request, response)
{
    var path = url.parse(request.url).pathname;
    var date = new Date();

    //console.log(date.toLocaleTimeString() + " " + path);

    if (path.indexOf("/TERMRX") == 0) {
      if (serialPort != 0 && fs.existsSync(datafile)) {
        fs.readFile(datafile, function (err, data) {
          if (err) { 
            console.log("Can't read file "+path);
          }
          else if (serialPort == 0) {
            console.log(portfile + ' receive()');
          }
          //console.log(data);
          fs.writeFileSync(datafile, "");
          response.writeHead(200, { 'Content-Type': 'text/plain' });
          response.end(Buffer(data), "text/plain");
        });
      }
      else {
        response.writeHead(200, { 'Content-Type': 'text/plain' });
        response.end("", "text/plain");
      }
    }
    else if (path.indexOf("/TERMTX") == 0) {
      var buffer = path.replace("/TERMTX/","");
      serialPort.write(buffer, function(err) {
        if (err) {
          console.log("Error writing serial port.");
        }
      });
      response.writeHead(200, { 'Content-Type': 'text/plain' });
      response.end("", "text/plain");
    }
    else if (path.indexOf("/TERMSTART") == 0) {
      //if (fs.existsSync(datafile)) {
        fs.readFile(portfile, function (err, data) {
          if (err) { 
            console.log("Can't read file "+path);
          }
          else if (serialPort == 0) {
            var s = String(data);
            s = s.trim();
            serialPort = new com.SerialPort(s, {
              baudrate: 115200,
              parser: com.parsers.readline('\n')
            });
            serialPort.on('data', function(data) {
              serialReceive(data);
              //serialReceive(String(data));
            });
            console.log(portfile + ' open()');
          }
          response.writeHead(200, { 'Content-Type': 'text/plain' });
          response.end("", "text/plain");
        });
/*
      }
      else {
        response.writeHead(200, { 'Content-Type': 'text/plain' });
        response.end("", "text/plain");
      }
*/
    }
    else if (path.indexOf("/TERMSTOP") == 0) {
      if (serialPort != 0) {
        serialPort.close(function() {
          console.log(portfile + ' closed()');
          serialPort = 0;
        });
        response.writeHead(200, { 'Content-Type': 'text/plain' });
        response.end("", "text/plain");
      }
    }
    else {
      var filename = pathobj.join(process.cwd(),path);
      if (fs.existsSync(filename)) {
        if(fs.statSync(filename).isDirectory()) {
          filename += 'comport.html';
        }
        fs.readFile(filename, "binary", function(error, file) {
          if(error) {
            response.writeHead(500, { 'Content-Type': 'text/plain' });
            response.end(error+"\n", "utf-8");
            // write an error response or nothing here
            return;
          }
          var type = 'text/html';
          var fend = "utf-8";
          if(filename.substr(-3) == 'css') {
            type = 'text/css';
          }
          else if(filename.substr(-3) == 'png') {
            type = 'image/png';
            fend = "binary";
          }
          else if(filename.substr(-2) == 'js') {
            type = 'text/javascript';
          }
          response.writeHead(200, { 'Content-Type': type });
          response.end(file, fend);
          //console.log(filename + " " + type);
        });
      } else {
        response.writeHead(404, { 'Content-Type': 'text/plain' });
        response.end("404 Not Found", "utf-8");
      }
    }
}).listen(8250);

